#
#    Copyright (C) 2016 Francisco Javier Parra <franparpe@openmailbox.org>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
#

from PyQt5.QtWidgets import QFrame
from PyQt5.QtWidgets import QGroupBox
from PyQt5.QtWidgets import QGridLayout
from PyQt5.QtWidgets import QLabel
from PyQt5.QtWidgets import QLineEdit

from PyQt5 import QtCore

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s


class GeometricParameters(QFrame):
    """A box that contains all paramters
    """
    def __init__(self, parent):
        "Initializing"
        super(GeometricParameters, self).__init__(parent)
        # sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
        # Aesthetics
        self.setFrameShape(self.StyledPanel)
        self.setFrameShadow(self.Raised)

        # Main layout
        self.grid = QGridLayout(self)

        # Group Box
        self.groupBox = QGroupBox(self)
        self.groupBox.setTitle(_fromUtf8("Geometric parameters"))
        self.grid.addWidget(self.groupBox, 0, 0, 1, 1)

        # Grid for placing the rest of widgets
        self.grid4Parameters = QGridLayout(self.groupBox)

        # Base Radius
        self.baseRadiusLabel = QLabel(self.groupBox)
        self.baseRadiusLabel.setText(_fromUtf8("Base radius (Rb) [mm]:"))
        self.baseRadiusLEdit = QLineEdit(self.groupBox)

        # Layout
        self.grid4Parameters.addWidget(self.baseRadiusLabel,
                                       0, 0, 1, 1)
        self.grid4Parameters.addWidget(self.baseRadiusLEdit,
                                       0, 1, 1, 1)

        # Summon default Layout
        self.CreateFlatTranslationUnilateral()

    def CreateFlatTranslationUnilateral(self):
        """Create a layout for the parameters corresponding
        to a cam-follower with unilateral contact and a
        translation followera with a flat face
        """
        self.identifyer = 0
        # Labels
        self.excentricityLabel = QLabel(self.groupBox)
        self.excentricityLabel.setText(_fromUtf8("Follower excentricity (ε) [mm]:"))
        self.betaInclinationLabel = QLabel(self.groupBox)
        self.betaInclinationLabel.setText(_fromUtf8("Follower inclination (β) [mm]:"))

        # Line edits
        self.excentricityLEdit = QLineEdit(self.groupBox)
        self.betaInclinationLEdit = QLineEdit(self.groupBox)

        # Layout
        self.grid4Parameters.addWidget(self.excentricityLabel,
                                       1, 0, 1, 1)
        self.grid4Parameters.addWidget(self.excentricityLEdit,
                                       1, 1, 1, 1)
        self.grid4Parameters.addWidget(self.betaInclinationLabel,
                                       2, 0, 1, 1)
        self.grid4Parameters.addWidget(self.betaInclinationLEdit,
                                       2, 1, 1, 1)

    def CreateCircularTranslationUnilateral(self):
        """Create the layout for the parameters corresponding
        to a cam-follower with unilateral contact and a...
        """
        self.identifyer = 1
        # Labels
        self.excentricityLabel = QLabel(self.groupBox)
        self.excentricityLabel.setText(_fromUtf8("Follower excentricity (ε) [mm]:"))
        self.rollerRadiusLabel = QLabel(self.groupBox)
        self.rollerRadiusLabel.setText(_fromUtf8("Roller radius (Rr) [mm]:"))

        # Line edits
        self.excentricityLEdit = QLineEdit(self.groupBox)
        self.rollerRadiusLEdit = QLineEdit(self.groupBox)

        # Layout
        self.grid4Parameters.addWidget(self.excentricityLabel,
                                       1, 0, 1, 1)
        self.grid4Parameters.addWidget(self.excentricityLEdit,
                                       1, 1, 1, 1)
        self.grid4Parameters.addWidget(self.rollerRadiusLabel,
                                       2, 0, 1, 1)
        self.grid4Parameters.addWidget(self.rollerRadiusLEdit,
                                       2, 1, 1, 1)

    def CreateFlatAngularUnilateral(self):
        self.identifyer = 2
        # Labels
        self.distBetwRotationCentersLabel = QLabel(self.groupBox)
        self.distBetwRotationCentersLabel.setText(_fromUtf8("Distance between rotation centers (l1) [mm]:"))
        self.armFollowerLabel = QLabel(self.groupBox)
        self.armFollowerLabel.setText(_fromUtf8("Arm follower (l2) [mm]:"))

        # Line edits
        self.distBetwRotationCentersLEdit = QLineEdit(self.groupBox)
        self.armFollowerLEdit = QLineEdit(self.groupBox)

        # Layout
        self.grid4Parameters.addWidget(self.distBetwRotationCentersLabel,
                                       1, 0, 1, 1)
        self.grid4Parameters.addWidget(self.distBetwRotationCentersLEdit,
                                       1, 1, 1, 1)
        self.grid4Parameters.addWidget(self.armFollowerLabel,
                                       2, 0, 1, 1)
        self.grid4Parameters.addWidget(self.armFollowerLEdit,
                                       2, 1, 1, 1)

    def CreateCircularAngularUnilateral(self):
        self.identifyer = 3
        # Labels
        self.distBetwRotationCentersLabel = QLabel(self.groupBox)
        self.distBetwRotationCentersLabel.setText(_fromUtf8("Distance between rotation centers (l1) [mm]:"))
        self.armFollowerLabel = QLabel(self.groupBox)
        self.armFollowerLabel.setText(_fromUtf8("Arm length to roller (l3) [mm]:"))
        self.rollerRadiusLabel = QLabel(self.groupBox)
        self.rollerRadiusLabel.setText(_fromUtf8("Roller radius (Rr) [mm]:"))

        # Line edits
        self.distBetwRotationCentersLEdit = QLineEdit(self.groupBox)
        self.armFollowerLEdit = QLineEdit(self.groupBox)
        self.rollerRadiusLEdit = QLineEdit(self.groupBox)

        # Layout
        self.grid4Parameters.addWidget(self.rollerRadiusLabel,
                                       1, 0, 1, 1)
        self.grid4Parameters.addWidget(self.rollerRadiusLEdit,
                                       1, 1, 1, 1)
        self.grid4Parameters.addWidget(self.distBetwRotationCentersLabel,
                                       2, 0, 1, 1)
        self.grid4Parameters.addWidget(self.distBetwRotationCentersLEdit,
                                       2, 1, 1, 1)
        self.grid4Parameters.addWidget(self.armFollowerLabel,
                                       3, 0, 1, 1)
        self.grid4Parameters.addWidget(self.armFollowerLEdit,
                                       3, 1, 1, 1)

    def _DestroyFlatTranslationUnilateral(self):
        self.excentricityLabel.deleteLater()
        self.betaInclinationLabel.deleteLater()
        self.excentricityLEdit.deleteLater()
        self.betaInclinationLEdit.deleteLater()

    def _DestroyCircularTranslationUnilateral(self):
        self.excentricityLabel.deleteLater()
        self.rollerRadiusLabel.deleteLater()
        self.excentricityLEdit.deleteLater()
        self.rollerRadiusLEdit.deleteLater()

    def _DestroyFlatAngularUnilateral(self):
        self.armFollowerLabel.deleteLater()
        self.armFollowerLEdit.deleteLater()
        self.distBetwRotationCentersLabel.deleteLater()
        self.distBetwRotationCentersLEdit.deleteLater()

    def _DestroyCircularAngularUnilateral(self):
        self.armFollowerLabel.deleteLater()
        self.armFollowerLEdit.deleteLater()
        self.distBetwRotationCentersLabel.deleteLater()
        self.distBetwRotationCentersLEdit.deleteLater()
        self.rollerRadiusLabel.deleteLater()
        self.rollerRadiusLEdit.deleteLater()

    def CreateFlatTranslationDesmodromic(self):
        """Creates the desmodromic layout
        """
        # Utilize what have been done
        self.CreateFlatTranslationUnilateral()
        self.identifyer = 4
        # Labels
        self.separationLabel = QLabel(self.groupBox)
        sepLabelContent = _fromUtf8("Distance between arms (dc) [mm]")
        self.separationLabel.setText(sepLabelContent)

        # Line edits
        self.separationLEdit = QLineEdit(self.groupBox)

        # Placing the content in the container
        self.grid4Parameters.addWidget(self.separationLabel,
                                       3, 0, 1, 1)
        self.grid4Parameters.addWidget(self.separationLEdit,
                                       3, 1, 1, 1)

    def CreateCircularTranslationDesmodromic(self):
        self.CreateCircularTranslationUnilateral()
        self.identifyer = 5
        # Labels
        self.separationLabel = QLabel(self.groupBox)
        sepLabelContent = _fromUtf8("Distance between arms (dc) [mm]")
        self.separationLabel.setText(sepLabelContent)

        # Line Edits
        self.separationLEdit = QLineEdit(self.groupBox)

        # Placing
        self.grid4Parameters.addWidget(self.separationLabel,
                                       3, 0, 1, 1)
        self.grid4Parameters.addWidget(self.separationLEdit,
                                       3, 1, 1, 1)

    def CreateFlatAngularDesmodromic(self):
        self.identifyer = 6
        # Labels
        self.distBetwRotationCentersLabel = QLabel(self.groupBox)
        self.distBetwRotationCentersLabel.setText(_fromUtf8("Distance between rotation centers (l1) [mm]:"))
        self.angleApertureLabel = QLabel(self.groupBox)
        content = _fromUtf8("Aperture angle between arms (β) [º]:")
        self.angleApertureLabel.setText(content)

        # Line edit
        self.angleApertureLEdit = QLineEdit(self.groupBox)
        self.distBetwRotationCentersLEdit = QLineEdit(self.groupBox)
        
        # Placing on the container
        self.grid4Parameters.addWidget(self.distBetwRotationCentersLabel,
                                       1, 0, 1, 1)
        self.grid4Parameters.addWidget(self.distBetwRotationCentersLEdit,
                                       1, 1, 1, 1)
        self.grid4Parameters.addWidget(self.angleApertureLabel,
                                       2, 0, 1, 1)
        self.grid4Parameters.addWidget(self.angleApertureLEdit,
                                       2, 1, 1, 1)

    def CreateCircularAngularDesmodromic(self):
        self.identifyer = 7
        # Labels
        self.rollerRadiusLabel = QLabel(self.groupBox)
        self.distBetwRotationCentersLabel = QLabel(self.groupBox)
        self.upperArmLengthLabel = QLabel(self.groupBox)
        self.lowerArmLengthLabel = QLabel(self.groupBox)
        contentsl3Sup = _fromUtf8("Upper arm length to roller (l3) [mm]")
        contentsl3Inf = _fromUtf8("Lower arm length to roller (l3) [mm]")
        contentl1 = _fromUtf8("Distance between rotation centers (l1) [mm]")
        self.rollerRadiusLabel.setText(_fromUtf8("Roller radius (Rr) [mm]"))
        self.distBetwRotationCentersLabel.setText(contentl1)
        self.upperArmLengthLabel.setText(contentsl3Sup)
        self.lowerArmLengthLabel.setText(contentsl3Inf)
        self.angleApertureLabel = QLabel(self.groupBox)
        content = _fromUtf8("Aperture angle between arms (β) [º]:")
        self.angleApertureLabel.setText(content)

        # Line edits
        self.rollerRadiusLEdit = QLineEdit(self.groupBox)
        self.distBetwRotationCentersLEdit = QLineEdit(self.groupBox)
        self.upperArmLengthLEdit = QLineEdit(self.groupBox)
        self.lowerArmLengthLEdit = QLineEdit(self.groupBox)
        self.angleApertureLEdit = QLineEdit(self.groupBox)

        # Placing Everything
        self.grid4Parameters.addWidget(self.rollerRadiusLabel,
                                       1, 0, 1, 1)
        self.grid4Parameters.addWidget(self.rollerRadiusLEdit,
                                       1, 1, 1, 1)
        self.grid4Parameters.addWidget(self.distBetwRotationCentersLabel,
                                       2, 0, 1, 1)
        self.grid4Parameters.addWidget(self.distBetwRotationCentersLEdit,
                                       2, 1, 1, 1)
        self.grid4Parameters.addWidget(self.upperArmLengthLabel,
                                       3, 0, 1, 1)
        self.grid4Parameters.addWidget(self.upperArmLengthLEdit,
                                       3, 1, 1, 1)
        self.grid4Parameters.addWidget(self.lowerArmLengthLabel,
                                       4, 0, 1, 1)
        self.grid4Parameters.addWidget(self.lowerArmLengthLEdit,
                                       4, 1, 1, 1)
        self.grid4Parameters.addWidget(self.angleApertureLabel,
                                       5, 0, 1, 1)
        self.grid4Parameters.addWidget(self.angleApertureLEdit,
                                       5, 1, 1, 1)

    def _DestroyFlatTranslationDesmodromic(self):
        self._DestroyFlatTranslationUnilateral()
        self.separationLabel.deleteLater()
        self.separationLEdit.deleteLater()

    def _DestroyCircularTranslationDesmodromic(self):
        self._DestroyCircularTranslationUnilateral()
        self.separationLabel.deleteLater()
        self.separationLEdit.deleteLater()

    def _DestroyFlatAngularDesmodromic(self):
        self.distBetwRotationCentersLabel.deleteLater()
        self.distBetwRotationCentersLEdit.deleteLater()
        self.angleApertureLabel.deleteLater()
        self.angleApertureLEdit.deleteLater()

    def _DestroyCircularAngularDesmodromic(self):
        self.rollerRadiusLabel.deleteLater()
        self.rollerRadiusLEdit.deleteLater()
        self.distBetwRotationCentersLabel.deleteLater()
        self.distBetwRotationCentersLEdit.deleteLater()
        self.upperArmLengthLabel.deleteLater()
        self.upperArmLengthLEdit.deleteLater()
        self.lowerArmLengthLabel.deleteLater()
        self.lowerArmLengthLEdit.deleteLater()
        self.angleApertureLabel.deleteLater()
        self.angleApertureLEdit.deleteLater()

    def DestroyPrevious(self):
        if self.identifyer == 0:
            self._DestroyFlatTranslationUnilateral()
        elif self.identifyer == 1:
            self._DestroyCircularTranslationUnilateral()
        elif self.identifyer == 2:
            self._DestroyFlatAngularUnilateral()
        elif self.identifyer == 3:
            self._DestroyCircularAngularUnilateral()
        elif self.identifyer == 4:
            self._DestroyFlatTranslationDesmodromic()
        elif self.identifyer == 5:
            self._DestroyCircularTranslationDesmodromic()
        elif self.identifyer == 6:
            self._DestroyFlatAngularDesmodromic()
        elif self.identifyer == 7:
            self._DestroyCircularAngularDesmodromic()

    def getBaseRadius(self):
        """Returns the base radius value
        """
        return float(self.baseRadiusLEdit.text())

    def getExcentricity(self):
        """Return the excentricity
        """
        return float(self.excentricityLEdit.text())

    def getInclination(self):
        """Returns the inclination introduced
        """
        return float(self.betaInclinationLEdit.text())

    def getRollerRadius(self):
        """Returns the roller radius introduced
        """
        return float(self.rollerRadiusLEdit.text())

    def getDistanceBetRotationCenters(self):
        """Returns the distance between rotation
        Angles 
        """
        return float(self.distBetwRotationCentersLEdit.text())

    def getArmFollowerLong(self):
        """Returns the arm length
        """
        return float(self.armFollowerLEdit.text())

    def getArmSeparation(self):
        """Return the arm separation introduced
        """
        return float(self.separationLEdit.text())

    def getUpperArmLength(self):
        """Return the length of the upper arm
        """
        return float(self.upperArmLengthLEdit.text())

    def getLowerArmLength(self):
        """Returns the length of the lower arm
        """
        return float(self.lowerArmLengthLEdit.text())

    def getArmsAperture(self):
        """Returns the aperture between arms in
        degrees
        """
        return float(self.angleApertureLEdit.text())
